<?php

define( 'FORM_PARENT_PATH', dirname(__FILE__) );

/*

    Simple Feedback Form v0.1
    -----------------------------------
    author: jah
    date:   2009-04-21T20:28:00 +01:00


    This simple feedback/contact form is simple to install and simple to
    configure.  Enjoy!


    Features:
        o Validate Input, Encode Output (VIEO!) (naturally ;)
        o UTF-8 (multibyte) support.


    Installation:
    Change the INCLUDES definition (below) to the path (including trailing slash)
    to the include files (located originally in the "inc" directory) relative to
    this file (originally named contact.php).
    e.g. If this file is in "/" and the include files are in
        /includes/contact_form/ then INCLUDE should be defined as
        'includes/contact_form/'
    Once INCLUDE is correctly defined read "config.inc.php" to learn how to set-up
    the form.

*/
define( 'INCLUDES', 'inc/' );
/*

    CHANGELOG:
        o 2009-04-20T22:49:00 +01:00
            Created contact.php.



*/


define( 'INCS', FORM_PARENT_PATH . '/' . INCLUDES );

require_once( INCS . 'config.inc.php' );
require_once( INCS . 'form.inc.php' );
require_once( INCS . 'markup.inc.php' );
require_once( INCS . 'utils.inc.php' );

// Check that the configuration is sane.
check_config();

// Populate a new Form object with required controls
$contact_form = Form::getInstance( $controls_config );

// Start or resume our session
session_start();

// Adds a unique hash as a session variable 'token' if it doesn't exist.
gen_token();

$dynamic_content = '';


if ( empty($_POST) )
{

    // SHOW EMPTY FORM READY FOR SUBMISSION
    display_form();

}


// We now assume we have POST data and tread carefully.
else
{
    //checking post header against config for sanity
    foreach( $controls_config as $eKey => $eValue )
    {
        // check the names of controls
        if ( !array_key_exists($eKey, $_POST) )
        {
            trigger_error( get_log_entry("Expected a field named: $eKey in the POST header!"), E_USER_WARNING );
            display_nice_error();
        }
        if ( !isset($_POST[$eKey]) )
        {
            trigger_error( get_log_entry("Expected a value for: $eKey - got NULL in the POST header!"), E_USER_WARNING );
            display_nice_error();
        }
    }

    // Check we have a token in session data
    if ( !isset($_SESSION['token']) )
    {
        trigger_error( get_log_entry("Couldn't find a key named 'token' in session data.  Something is wrong!)"), E_USER_WARNING );
        display_nice_error();

    }

    // Validate the token and assign to Form::clean_token
    if ( !$contact_form->set_form_token( &$_POST['Token'] ) )
    {
        $sfl_token = safe_for_logging( &$_POST['Token'], 40, '' );
        if ( empty($sfl_token) ) $sfl_token = "and cannot be logged.";
        trigger_error( get_log_entry("The token from the form was invalid $sfl_token."), E_USER_WARNING );
        display_nice_error();
    }

    // check the form token matches the session token
    if ( $_SESSION['token'] != $contact_form->clean_token )
    {
        trigger_error( get_log_entry("The token from the form did not match the token stored in the session data." .
            "This might mean form re-submission. The token was {$contact_form->clean_token}."), E_USER_WARNING );
        display_nice_error();

    }


    // User is not allowed to post more than twice and can't post the same form twice - in the same session.
    if ( isset($_SESSION['form_success']) )
    {
        if ( count($_SESSION['form_success']) >= 2 )
        {
            // Already submitted twice - get orf my laaand.
            trigger_error( get_log_entry("A user has attempted to exceed the allowed maximum of two form submissions."), E_USER_WARNING );
            display_nice_error();

        }
        else if ( isset($_SESSION['form_success'][$contact_form->clean_token]) )
        {
            // This Form already posted in this session
            trigger_error( get_log_entry("User has tried to resubmit a contact form already successfully submitted this session" .
                " - this should not happen! token: {$contact_form->clean_token}"), E_USER_WARNING );
            display_nice_error();

        }
    }


    //
    // FORM SUBMISSION
    //
    $error_count = $contact_form->do_submission();

    if ( $error_count == 0 )
    {
        if ( !isset($_SESSION['form_success']) ) $_SESSION['form_success'] = array();
        $_SESSION['form_success'][$contact_form->clean_token] = 1;
        unset($_SESSION['token']);

        // FORM SUBMISSION SUCCESS
        display_form_success();

    } else {

        // VALIDATION ERRORS
        display_form();

    }
}


// Output functions - one of these is called depending on what the user should
// see.

function display_nice_error()
{
    $loc  = '';
    $loc .= "http://{$_SERVER['SERVER_NAME']}"; // TODO dangerous! surely?
    $loc .= dirname($_SERVER['SCRIPT_NAME']);
    if ( !has_trailing_pathsep( $loc ) ) $loc .= '/';
    $loc .= "sorry.html";

    header("Location: $loc", 1, 303);
    exit;
}

function display_form()
{
    global $markup_page_head, $markup_page_foot, $form_config;
    $dynamic_content = '';
    $dynamic_content .= $markup_page_head;
    $dynamic_content .= Form::getInstance()->displayForm($form_config);
    $dynamic_content .= $markup_page_foot;

    echo( $dynamic_content );
    exit;
}

function display_form_success()
{
    $loc  = '';
    $loc .= "http://{$_SERVER['SERVER_NAME']}"; // TODO dangerous! surely?
    $loc .= dirname($_SERVER['SCRIPT_NAME']);
    if ( !has_trailing_pathsep( $loc ) ) $loc .= '/';
    $loc .= "thank-you.html";

    header("Location: $loc", 1, 303);
    exit;
}

function has_trailing_pathsep( $s )
{
    $t = mb_substr( $s, -1 );
    if ( $t == "\\" || $t == "/" ) return true;
    return false;
}


?>
